package com.feicheng.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.feicheng.BitwiseComparison;
import com.feicheng.TimeSlotGenerator;
import com.feicheng.common.exception.SystemException;
import com.feicheng.common.result.ResultInfo;
import com.feicheng.common.task.Cache;
import com.feicheng.common.util.StringGenerator;
import com.feicheng.persistence.entity.*;
import com.feicheng.persistence.service.*;
import com.feicheng.service.IFOrderService;
import com.feicheng.wxapi.pay.WxAppPayBean;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

@Service
public class FOrderServiceImpl implements IFOrderService {

    @Autowired
    IAOrderService iaOrderService;

    @Autowired
    IARoomService iaRoomService;

    @Autowired
    IClientService iClientService;

    @Autowired
    IAStoreService iaStoreService;

    @Autowired
    IAClientAmountService iaClientAmountService;

    @Autowired
    WxAppPayBean wxAppPayBean;


    @Autowired
    Cache cache;




    @Override
    public ResultInfo yuding(JSONObject param) {

        String roomid = param.getString("roomid");

        if (!StringUtils.hasLength(roomid)) {
            throw new SystemException("房间ID缺失，预定无法完成。");
        }

        ARoom room = iaRoomService.getById(roomid);

        if (null == room) {
            throw new SystemException("房间不存在");
        }

        if (!"CD".equals(room.getStatu())) {
            throw new SystemException("房间无法预定");
        }

        String st = param.getString("st");

        if (!StringUtils.hasLength(st)) {
            throw new SystemException("开始时间缺失，预定无法完成。");
        }

        String et = param.getString("et");

        if (!StringUtils.hasLength(et)) {
            throw new SystemException("结束时间缺失，预定无法完成。");
        }

        String clientid = param.getString("clientid");

        Client client = iClientService.getById(clientid);

        if (!StringUtils.hasLength(clientid)) {
            throw new SystemException("客户缺失，预定无法完成。");
        }

        LocalDateTime lst = LocalDateTime.parse(st, DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss"));
        LocalDateTime let = LocalDateTime.parse(et, DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss"));

        synchronized (cache) {

            if (cache.containsKey(roomid)) {
                JSONObject roomTemp = cache.getJSONObject(roomid);
                JSONObject currentObj = TimeSlotGenerator.generateTimeSlots(lst, let);
                for (Iterator<Map.Entry<String, Object>> ittemp = currentObj.entrySet().iterator();
                     ittemp.hasNext(); ) {
                    Map.Entry<String, Object> entry = ittemp.next();

                    String dateKey = entry.getKey();
                    String dateStr = entry.getValue().toString();

                    if (roomTemp.containsKey(dateKey)) {
                        String currentRoomDateStr = roomTemp.getString(dateKey);

                        String tempStr = BitwiseComparison.compareBits(dateStr, currentRoomDateStr);

                        if (tempStr.contains("1")) {
                            throw new SystemException("当前时段被占用，预约失败，请选择其他时段。");
                        }
                    }
                }
            }
        }

        // 检查余额
        Duration duration = Duration.between(lst, let);

        // 获取分钟数
        long minutes = duration.toMinutes();

        int amount = (int)minutes * room.getPrice();

        QueryWrapper<AClientAmount> acaWrapper = new QueryWrapper<>();
        acaWrapper.eq("clientid", clientid);
        acaWrapper.eq("storeid", room.getStoreid());
        AStore store = iaStoreService.getById(room.getStoreid());
        AClientAmount currentAmount = iaClientAmountService.getOne(acaWrapper);
        if (null != currentAmount && currentAmount.getAmount() > amount) {
            currentAmount.setAmount(currentAmount.getAmount() - amount);
            iaClientAmountService.updateById(currentAmount);

            AOrder order = new AOrder();
            order.setOrderid(StringGenerator.getID("OD"));
            order.setClientid(clientid);
            order.setRoomid(roomid);
            order.setClientnc(client.getNc());
            order.setStoreid(room.getStoreid());
            order.setSname(store.getName());
            order.setRprice(room.getPrice());
            order.setAmount(amount);
            order.setSt(lst);
            order.setEt(let);
            order.setStatu("UD");
            order.setCt(LocalDateTime.now());
            order.setUt(LocalDateTime.now());
            order.setCu(clientid);
            order.setUu(clientid);

            iaOrderService.save(order);
        } else {
            String orderid = StringGenerator.getID("OD");
            StringBuilder sb = new StringBuilder(roomid);
            sb.append(",").append(lst.format(DateTimeFormatter.ofPattern("yyyyMMddhhmmss")));
            sb.append(",").append(let.format(DateTimeFormatter.ofPattern("yyyyMMddhhmmss")));
            sb.append(",").append(clientid);
            PrepayWithRequestPaymentResponse prepayData =
                    wxAppPayBean.jsapi(orderid,
                            "支付订单",
                            "/notice-url/"+orderid,
                            amount,
                            client.getOpenid(),
                            sb.toString()
                            );

            return ResultInfo.success(prepayData);
        }


        return ResultInfo.success();
    }
}
